Conversation
Introduce backupTenantSchemaToDisk.ts and npm run backup:tenant-schema. Default run copies tenantSchema documents into tenantSchemaBackup using the shared tenantSchemaBackup helpers; --dry-run writes JSON under scripts/output only. Extend createBackupDocId with an optional shared timestamp for batched disk exports. Document usage in docs/TENANT_SCHEMA_BACKUP.md and link from SCHEMA_SYNC_GUIDE and scripts/README. Co-authored-by: Cursor <cursoragent@cursor.com>
`enforceRequestLimits` previously fetched every booking for the user's email and filtered the time window in memory. For heavy users that's O(N) reads per booking attempt, plus an `in` query on bookingLogs for every requestNumber returned. On App Engine F1 this dominates the per-request Firestore cost and adds to instance memory pressure. Pre-compute the windows for every configured period, take the earliest start, and add `requestedAt >= earliestStart` to the Firestore query so only the bookings that can possibly matter come back. The per-period in-memory aggregation now reuses these windows instead of recomputing them. Requires a new composite index `(email ASC, requestedAt ASC)` on each tenant's bookings collection; added to firestore.indexes.json for mc-bookings and itp-bookings. NOTE: deploy the indexes (`firebase deploy --only firestore:indexes`) before this change reaches production — without the index the bounded query throws and the existing fail-open try/catch silently disables enforcement. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
# Conflicts: # booking-app/firestore.indexes.json
Asserts that when the request-limits endpoint returns 429 the BookingStatusBar shows the server's error message and the Next button is disabled. This is the only UI-level guard against shipping a regression that silently disables enforcement. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
# Conflicts: # booking-app/components/src/client/routes/components/SchemaProvider.tsx # booking-app/package.json # booking-app/tests/unit/schema-completeness.unit.test.ts
The tenant schema migration changed top-level `tenant` from a string slug to a TenantBranding object. `useCheckRequestLimits` still keyed its "schema loaded" guard and effect dependency on `schema.tenant`, which is now always a truthy object compared by identity. Switch to `schema.tenantId` (the new string slug) so the guard works again and the effect dependency is a stable primitive. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…mmit migrateTenantSchemaFirestore.ts and coerce-tenant-schema-migration.unit.test.ts come from main's tenant-schema migration and must be kept in this merge. They were unintentionally removed in the previous commit; restore them verbatim from origin/main. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Support request limit
…1238) All tenant docs (prod/staging/default, mc + itp) are stored in the canonical nested shape now that the Phase 2 migration has been applied, so the read-time backward-compat layer is no longer needed. - coerceTenantSchema: drop the legacy flat-schema branch and the partial-migration shims (mapLegacyEmailMessages, agreements -> attestations fallback, legacy resource training mapping, top-level timeSensitiveRequestWarning pickup). It is now a new-shape merge over the tenant defaults (~388 -> ~70 lines). - Delete the one-off migration tooling it has already run: scripts/migrateTenantSchemaFirestore.ts, its detection helpers (tenantSchemaFirestoreDocNeedsShapeMigration / isNestedTenantSchemaDocument / STALE_LEGACY_* / isNewSchemaShape), and the migrate:tenant-schema[:dry-run] npm scripts. - Remove deprecated type aliases Agreement / PermissionLabels and the defaultAgreement const (Attestation / ContextLabels / defaultAttestation are the canonical names). - Update unit tests that ran legacy-shaped fixtures through coerce to use the nested shape; delete the migration-detection unit test. Satisfies the #1238 goal of removing the legacy field names from code. type-check clean; unit suite green.
The deploy workflows created Firestore composite indexes from a hard-coded list duplicated across all three environment files. That list also omitted the (email, requestedAt) index that the request-limits feature (#1403) requires, so request-limit queries failed with FAILED_PRECONDITION and the fail-open enforcement silently allowed bookings through. Make firestore.indexes.json the single source of truth and add scripts/deploy-firestore-indexes.sh, which reads that file and runs 'gcloud firestore indexes composite create' for each index against the environment's database. Each workflow's 'Deploy Firestore indexes' step now just invokes the script with its database id. Adding/changing an index is now a one-line edit to firestore.indexes.json with no workflow changes. The (email, requestedAt) index is already present in firestore.indexes.json (added in #1403), so this also provisions it. We keep gcloud rather than 'firebase deploy --only firestore:indexes' because firebase-tools 15.x throws on the multi-database firestore array in firebase.json. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
refactor(schema): remove legacy tenantSchema compat code (Phase 3 of #1238)
ci(firestore): drive index deploy from firestore.indexes.json (single source)
Bumps the npm_and_yarn group with 1 update in the /booking-app directory: [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest). Updates `vitest` from 3.2.4 to 3.2.6 - [Release notes](https://github.com/vitest-dev/vitest/releases) - [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md) - [Commits](https://github.com/vitest-dev/vitest/commits/v3.2.6/packages/vitest) --- updated-dependencies: - dependency-name: vitest dependency-version: 3.2.6 dependency-type: direct:development dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] <support@github.com>
This branch was previously deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary of Changes
Production release: merge
mainintoprod. This aggregates ~1 month of changes (since the last prod release, #1493 on 2026-06-04). All commits were already reviewed and merged intomain.Notable changes included:
tenantSchemastructure and field names. #1238): removed legacy schema fields (refactor(schema): remove legacy tenantSchema compat code (Phase 3 of #1238) #1497), normalized tenant resource IDs to strings (Reapply "feat(schema): migrate tenant resources to string resource IDs" #1501, Fix tenant schema resouce id #1509), CLI backup for tenant schema. Verify the schema-diff dry-run on this PR shows the expected/zero diff before merging.Schema Changes
No tenant schema changes
Schema changed (describe below)
All tenants: tenant resource IDs normalized to strings (Refactor
tenantSchemastructure and field names. #1238 Phase 3 / Reapply "feat(schema): migrate tenant resources to string resource IDs" #1501). Data migration (Phase 2) was already applied in production; this release ships the corresponding code changes.Please confirm the automated PR Prod Schema Diff (development vs production tenantSchema dry-run) shows no unexpected diff before merging.
Checklist
git diff main...prodis empty; main is a superset of prod)Screenshots / Video
N/A — release PR. Individual changes carry their own screenshots on the linked PRs.